﻿using CoreCms.Net.Configuration;
using CoreCms.Net.IRepository;
using CoreCms.Net.IServices;
using CoreCms.Net.IServices.Pay;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.ViewModels.DTO;
using CoreCms.Net.Model.ViewModels.UI;
using CoreCms.Net.Utility.Extensions;
using CoreCms.Net.Utility.Helper;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CoreCms.Net.Services.Pay
{
    public class WalletPayServices : BaseServices<CoreCmsSetting>, IWalletPayServices
    {
        private readonly IServiceProvider _serviceProvider;
        private readonly ICoreCmsPaymentsServices _userPaymentServices;
        //private readonly ICoreCmsPaymentsRepository _Paymentdal;

        public WalletPayServices(IWeChatPayRepository dal, IServiceProvider serviceProvider, ICoreCmsPaymentsServices userPaymentServices)
        {
            BaseDal = dal;
            _serviceProvider = serviceProvider;
            _userPaymentServices = userPaymentServices;
        }

        /// <summary>
        ///     发起支付
        /// </summary>
        /// <param name="entity">实体数据</param>
        /// <returns></returns>
        public async Task<WebApiCallBack> PubPay(CoreCmsBillPayments entity, CoreCmsPayments paySetting)
        {
            using (var container = _serviceProvider.CreateScope())
            {
                var billPaymentsServices = container.ServiceProvider.GetService<ICoreCmsBillPaymentsServices>();

                var jm = new WebApiCallBack();
                var dyFmInfo = JsonConvert.DeserializeObject<JObject>(entity.parameters);
                var dyToInfo = JsonConvert.DeserializeObject<WalletPayment>(paySetting.parameters);
                try
                {
                    //查询token1余额
                    decimal rate = 1M;
#if DEBUG
                    rate = 0.01M;
#endif
                    var balance1 = ChainHelper.GetBalance(dyToInfo.token1, dyFmInfo["address"].ObjectToString(), dyToInfo.chain);
                    if (balance1 < entity.money * rate)
                    {
                        jm.msg = GlobalErrorCodeVars.Code10102 + "" + dyToInfo.token1;
                        jm.data = 10102;
                        return jm;
                    }
                    //查询token2余额
                    //var balance2 = ChainHelper.GetBalance(dyToInfo.token2, dyFmInfo["address"].ObjectToString(), dyToInfo.chain);
                    //if (balance2 < entity.moneyTYD * rate)
                    //{
                    //    jm.msg = GlobalErrorCodeVars.Code10102 + "" + dyToInfo.token2;
                    //    jm.data = 10102;
                    //    return jm;
                    //}
                    //构造交易1
                    var hash1 = ChainHelper.CreateTransfer(dyToInfo.token1, entity.money * rate, dyToInfo.address, dyFmInfo["address"].ObjectToString(), dyToInfo.chain);
                    ////构造交易2
                    //var hash2 = ChainHelper.CreateTransfer(dyToInfo.token2, entity.moneyTYD * rate, dyToInfo.address, dyFmInfo["address"].ObjectToString(), dyToInfo.chain, false);
                    var hash = hash1;// + "," + hash2;

                    //改变支付单状态
                    var billPaymentInfo = await billPaymentsServices.QueryByIdAsync(entity.paymentId);
                    if (billPaymentInfo == null)
                    {
                        jm.msg = GlobalErrorCodeVars.Code10056;
                        jm.data = 10056;
                        return jm;
                    }

                    jm.status = true;
                    jm.data = new { id = entity.paymentId, hash = hash, exer = $"user.p.{dyToInfo.chain.ToLower()}.token" };
                    jm.msg = "构造交易成功";

                    return jm;
                }
                catch (Exception eexx)
                {
                    jm.msg = eexx.Message;
                    jm.data = 500;
                    return jm;
                }
            }
        }

        public async Task<WebApiCallBack> PubPaySend(CoreCmsBillPayments entity, CoreCmsPayments paySetting)
        {
            using (var container = _serviceProvider.CreateScope())
            {
                var billPaymentsServices = container.ServiceProvider.GetService<ICoreCmsBillPaymentsServices>();

                var jm = new WebApiCallBack();
                //var dyFmInfo = JsonConvert.DeserializeObject<JObject>(entity.parameters);
                var dyToInfo = JsonConvert.DeserializeObject<WalletPayment>(paySetting.parameters);

                try
                {
                    string signHash = ChainHelper.SendTransfer(dyToInfo.token1, entity.tradeNo, dyToInfo.chain.ToUpper());

                    var resultBillPayment = await billPaymentsServices.ToUpdate(entity.paymentId,
                        (int)GlobalEnumVars.BillPaymentsStatus.Other, "walletpay", entity.money, "交易广播中", signHash);

                    jm.status = true;
                    jm.data = new { id = entity.paymentId, hash = signHash, token = dyToInfo.token1, chain = dyToInfo.chain.ToUpper() };
                    jm.msg = "交易广播成功";

                    return jm;
                }
                catch (Exception eexx)
                {
                    jm.msg = eexx.Message;
                    jm.data = 500;
                    return jm;
                }
            }
        }

        public async Task<WebApiCallBack> PubPaySuccess(CoreCmsBillPayments entity, CoreCmsPayments paySetting)
        {
            using (var container = _serviceProvider.CreateScope())
            {
                var billPaymentsServices = container.ServiceProvider.GetService<ICoreCmsBillPaymentsServices>();

                var jm = new WebApiCallBack();
                var dyToInfo = JsonConvert.DeserializeObject<WalletPayment>(paySetting.parameters);

                try
                {
                    ChainRespon respon = ChainHelper.detail(dyToInfo.token1, entity.tradeNo, dyToInfo.chain.ToUpper());
                    if (respon.code == 0)
                    {
                        int data = Convert.ToInt32(respon.data);
                        if (data == 2)
                        {
                            jm.status = true;
                            await billPaymentsServices.ToUpdate(entity.paymentId, (int)GlobalEnumVars.BillPaymentsStatus.Payed, "walletpay", entity.money, "交易完成", entity.tradeNo);
                        }
                    }
                    //int maxSeconds = 60, seconds = 0, sleep = 5;
                    //while (seconds <= maxSeconds)
                    //{
                    //    seconds += sleep;
                    //    Thread.Sleep(sleep * 1000);
                    //    ChainRespon respon = ChainHelper.detail(dyToInfo.token1, entity.tradeNo, dyToInfo.chain.ToUpper());
                    //    if (respon.code == 0)
                    //    {
                    //        int data = Convert.ToInt32(respon.data);
                    //        if (data == 3) continue;
                    //        if (data == 2)
                    //            jm.status = true;
                    //        await billPaymentsServices.ToUpdate(entity.paymentId, data, "walletpay", entity.money, "交易完成", entity.tradeNo);
                    //    }
                    //}

                    jm.data = entity.paymentId;
                    jm.msg = "查询成功";

                    return jm;
                }
                catch (Exception eexx)
                {
                    jm.msg = eexx.Message;
                    jm.data = 500;
                    return jm;
                }
            }
        }

        /// <summary>
        ///     用户余额退款
        /// </summary>
        /// <param name="refundInfo">退款单数据</param>
        /// <param name="paymentInfo">支付单数据</param>
        /// <returns></returns>
        public async Task<WebApiCallBack> Refund(CoreCmsBillRefund refundInfo, CoreCmsBillPayments paymentInfo)
        {
            var jm = new WebApiCallBack();

            if (refundInfo.money == 0)
            {
                jm.status = true;
                jm.msg = "退款成功";
                jm.data = new
                {
                    ReturnCode = "SUCCESS"
                };
                return jm;
            }

            //var res = await _userPaymentServices.Change(paymentInfo.userId,
            //    (int)GlobalEnumVars.UserBalanceSourceTypes.Refund, refundInfo.money, paymentInfo.paymentId);
            //if (res.status == false) return jm;
            jm.status = true;
            jm.data = null;
            jm.msg = "退款成功";

            return jm;
        }
    }
}